home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Mac Game Programming Gurus / TricksOfTheMacGameProgrammingGurus.iso / More Source / Pascal / NewWatch / NewWatch.p < prev    next >
Text File  |  1995-04-25  |  16KB  |  639 lines

  1. {This program was written by Eric Kilk in 1985, as a Desk Accessory. It was revived in 1995 by Ken Long,}
  2. {who turned it into an application. After he posted it to alt.sources.mac, I (Ingemar R), modified it to give it}
  3. {some functionality I found lacking. New features:}
  4. {}
  5. {• Updates automatically}
  6. {• Resizeable}
  7. {• More hour marks}
  8. {• Optional digits (3, 6, 9 and 12), roman or arabic}
  9. {• Black or white}
  10. {}
  11. {Do you feel like working some more on it? Colorize? Seconds? Circular WDEF? Put it in the menu bar?}
  12. {More options?}
  13. {}
  14. {- Fixes 21 of april:}
  15. {• Checked the "can background" flag so it updates when in the background}
  16. {• Modified the hands so they draw correctly}
  17. {}
  18. {- 25 of April:}
  19. {Ken Long released his C version of this code, which added a second hand (Second}
  20. {hand code? I guess so.) and I really can't let the Pascal version fall behind… so I}
  21. {added seconds here too - but made it optional. So:}
  22. {• A hand for seconds.}
  23. {• Incorporated Ken's BNDL and icons.}
  24. {• Thicker hands as an option.}
  25. {• Added a circular WDEF. (Source to that is not included at this time.)}
  26. {• Checked the "Get front clicks" flag as suggested by someone in a.s.m.}
  27. {• Added project and IFC's for MetroWerks Pascal.}
  28.  
  29.  
  30. program NewWatch;
  31.  
  32. {$IFC UNDEFINED THINK_PASCAL}
  33.     uses
  34.         Types, QuickDraw, Events, Menus, Dialogs, Fonts, Resources, Devices;
  35. {$ENDC}
  36.  
  37.     const
  38.         appleID = 1;
  39.         fileID = 2;
  40.         editID = 3;
  41.         optionsID = 4;
  42.  
  43.         helpItem = 1;
  44.         defaultItem = 2;
  45.         quitItem = 4;
  46.  
  47.         kTwoPi = 6.2831;
  48.  
  49.     var
  50.         appleMenu, fileMenu, editMenu, optionsMenu: MenuHandle;
  51.  
  52.         clockWindow, whatWindow: WindowPtr;
  53.         dragRect: Rect;
  54.  
  55.     type
  56.         settingsType = packed record
  57.                 display: Integer;
  58.                 black: Boolean;
  59.                 seconds: Boolean;
  60.                 fancy: Boolean;
  61.             end;
  62.     var
  63.         settings: SettingsType;
  64.  
  65.         gDone, gHasWNE, gColorQDFlag, g32bQDFlag: Boolean;
  66.         gPrevDateTime: DateTimeRec;
  67.  
  68.     type
  69.         WindowTemplate = record
  70.                 boundsRect: Rect;
  71.                 procID: Integer;
  72.                 visible: Boolean;
  73.                 filler1: Boolean;
  74.                 goAwayFlag: Boolean;
  75.                 filler2: Boolean;
  76.                 refCon: LongInt;
  77.                 title: Str255;
  78.             end;
  79.         WindowTPtr = ^WindowTemplate;
  80.         WindowTHnd = ^WindowTPtr;
  81.     var
  82.         wt: WindowTHnd;
  83.  
  84.  
  85.  
  86.     procedure EK;
  87.     begin
  88.         Move(-3, 0);
  89.         Line(0, 4);
  90.         Move(1, -4);
  91.         Line(1, 0);
  92.         Move(-1, 2);
  93.         Line(0, 0);
  94.         Move(0, 2);
  95.         Line(1, 0);
  96.         Move(2, -4);
  97.         Line(0, 4);
  98.         Move(1, -2);
  99.         Line(2, -2);
  100.         Move(-1, 3);
  101.         Line(1, 1);
  102.     end; {EK}
  103.  
  104.     procedure DrawHands (dateTime: DateTimeRec);
  105.         var
  106.             mx, my, hx, hy, sx, sy: Integer;            {• hand end-points */}
  107.             m1x, m1y, m2x, m2y: Integer;
  108.             h1x, h1y, h2x, h2y: Integer;
  109.             r: Rect;
  110.             minUnit, min, hr, sec, secUnit: Double;            {• time */}
  111.             cxSize, cySize: Integer;
  112.             hourRgn, minuteRgn, secRgn: RgnHandle;
  113.         const
  114.             kSecondLength = 0.8;
  115.             kMinuteLength = 0.75;
  116.             kHourLength = 0.5;
  117.             kMinuteSpecial = 0.55;
  118.             kHourSpecial = 0.4;
  119.             kMinuteWidth = 0.07;
  120.             kHourWidth = 0.10;
  121.  
  122.         function Sgn (arg: Integer): Integer;
  123.         begin
  124.             if arg > 0 then
  125.                 Sgn := 1
  126.             else if arg < 0 then
  127.                 Sgn := -1
  128.             else
  129.                 Sgn := 0;
  130.         end; {Sgn}
  131.  
  132.     begin
  133.         SetPort(clockWindow);
  134.         cxSize := (clockWindow^.portRect.right - clockWindow^.portRect.left) div 2;
  135.         cySize := (clockWindow^.portRect.bottom - clockWindow^.portRect.top) div 2;
  136.         SetOrigin(-cxSize, -cySize);    {• make 0,0 in center */}
  137.  
  138.         minUnit := dateTime.minute / 60.0;
  139.         min := minUnit * kTwoPi;    {• 2*pi */}
  140.         hr := (dateTime.hour + minUnit) / 12.0 * kTwoPi;
  141.         mx := Trunc(kMinuteLength * cxSize * sin(min));
  142.         my := Trunc(-kMinuteLength * cySize * cos(min));
  143.         if settings.fancy then {Fancy hands}
  144.             begin
  145.                 m1x := Trunc(kMinuteSpecial * cxSize * sin(min + kMinuteWidth));
  146.                 m1y := Trunc(-kMinuteSpecial * cySize * cos(min + kMinuteWidth));
  147.                 m2x := Trunc(kMinuteSpecial * cxSize * sin(min - kMinuteWidth));
  148.                 m2y := Trunc(-kMinuteSpecial * cySize * cos(min - kMinuteWidth));
  149.             end;
  150.         hx := Trunc(kHourLength * cxSize * sin(hr));
  151.         hy := Trunc(-kHourLength * cySize * cos(hr));
  152.         if settings.fancy then {Fancy hands}
  153.             begin
  154.                 h1x := Trunc(kHourSpecial * cxSize * sin(hr + kHourWidth));
  155.                 h1y := Trunc(-kHourSpecial * cySize * cos(hr + kHourWidth));
  156.                 h2x := Trunc(kHourSpecial * cxSize * sin(hr - kHourWidth));
  157.                 h2y := Trunc(-kHourSpecial * cySize * cos(hr - kHourWidth));
  158.             end;
  159.  
  160. {Additions for seconds:}
  161.         if settings.seconds then
  162.             begin
  163.                 secUnit := dateTime.second / 60.0;
  164.                 sec := secUnit * kTwoPi;
  165.                 sx := Trunc(kSecondLength * cxSize * sin(sec));
  166.                 sy := Trunc(-kSecondLength * cySize * cos(sec));
  167.             end;
  168.  
  169.         hourRgn := NewRgn;
  170.         minuteRgn := NewRgn;
  171.         secRgn := NewRgn;
  172.  
  173.         if settings.seconds then
  174.             begin
  175.                 OpenRgn;
  176.                 MoveTo(0, 0);        {• create the seconds hand region}
  177.                 LineTo(sx, sy);
  178.                 if abs(sx) > abs(sy) then
  179.                     Line(0, Sgn(sx))
  180.                 else
  181.                     Line(-Sgn(sy), 0);
  182.                 Line(-sx, -sy);
  183.                 LineTo(0, 0);
  184.                 CloseRgn(secRgn);
  185.             end;
  186.  
  187.         OpenRgn;
  188.         MoveTo(0, 0);        {• create the minute hand region}
  189.         if settings.fancy then
  190.             LineTo(m2x, m2y);
  191.         LineTo(mx, my);
  192.         if abs(mx) > abs(my) then
  193.             Line(0, Sgn(mx))
  194.         else
  195.             Line(-Sgn(my), 0);
  196.         if settings.fancy then
  197.             begin
  198.                 Line(m1x - mx, m1y - my);
  199.                 Line(-m1x, -m1y);
  200.             end
  201.         else
  202.             Line(-mx, -my);
  203.         LineTo(0, 0);
  204.         CloseRgn(minuteRgn);
  205.  
  206.         OpenRgn;
  207.         MoveTo(0, 0);        {• create the hour hand region}
  208.         if settings.fancy then
  209.             LineTo(h2x, h2y);
  210.         LineTo(hx, hy);
  211.         if abs(hx) > abs(hy) then
  212.             Line(0, Sgn(hx))
  213.         else
  214.             Line(-Sgn(hy), 0);
  215.         if settings.fancy then
  216.             begin
  217.                 Line(h1x - hx, h1y - hy);
  218.                 Line(-h1x, -h1y);
  219.             end
  220.         else
  221.             Line(-hx, -hy);
  222.         LineTo(0, 0);
  223.         CloseRgn(hourRgn);
  224.  
  225.         UnionRgn(hourRgn, minuteRgn, minuteRgn);
  226.         if settings.seconds then
  227.             UnionRgn(secRgn, minuteRgn, minuteRgn);
  228.  
  229.         PaintRgn(minuteRgn);        {• draw the hands.}
  230.         DisposeRgn(minuteRgn);
  231.         DisposeRgn(hourRgn);
  232.         DisposeRgn(secRgn);
  233.  
  234.         {MoveTo(0, 0);        {• erase the center dot.}
  235.         {PenPat(white);}
  236.         {LineTo(0, 0);}
  237.         {PenPat(black);}
  238.     end; {DrawHands}
  239.  
  240.     procedure ShowClock;
  241.             {• draw the entire clock face */}
  242.         var
  243.             dateTime: DateTimeRec;    {• date gets read into here */}
  244.  
  245.             cxSize, cySize: Integer;
  246.  
  247.             fInfo: FontInfo;
  248.             theTextSize: Integer;
  249.     begin
  250.         SetPort(clockWindow);
  251.         PenNormal;
  252.         if settings.black then
  253.             PaintRect(clockWindow^.portRect)
  254.         else
  255.             EraseRect(clockWindow^.portRect);
  256.  
  257.         cxSize := (clockWindow^.portRect.right - clockWindow^.portRect.left) div 2;
  258.         cySize := (clockWindow^.portRect.bottom - clockWindow^.portRect.top) div 2;
  259.  
  260.         GetTime(dateTime);
  261.         if (dateTime.hour > 11) then
  262.             dateTime.hour := dateTime.hour - 12;
  263.         SetOrigin(-cxSize, -cySize);    {• make 0,0 in center */}
  264.         PenMode(srcXor);
  265.  
  266. {The text size is determined from the smallest side!}
  267.         if cxSize > cySize then
  268.             theTextSize := cySize div 5
  269.         else
  270.             theTextSize := cxSize div 5;
  271.  
  272.         TextSize(theTextSize);
  273.         GetFontInfo(fInfo);
  274.  
  275.         if (settings.display = 0) or (theTextSize < 6) then
  276.             begin
  277.                 MoveTo(0, cySize - 2);
  278.                 Line(0, 0);    {• draw 4 ticks.}
  279.                 MoveTo(cxSize - 2, 0);
  280.                 Line(0, 0);
  281.                 MoveTo(0, -cySize + 1);
  282.                 Line(0, 0);
  283.                 MoveTo(-cxSize + 1, 0);
  284.                 Line(0, 0);
  285.             end
  286.         else if settings.display = 1 then
  287.             begin
  288.                 PenMode(patXor);
  289.                 if settings.black then
  290.                     ForeColor(whiteColor);
  291.                 MoveTo(0 - StringWidth('6') div 2, cySize - 2);
  292.                 DrawString('6');
  293.                 MoveTo(cxSize - 0 - StringWidth('3'), 0 + fInfo.ascent div 2);
  294.                 DrawString('3');
  295.                 MoveTo(0 - StringWidth('12') div 2, -cySize + 0 + fInfo.ascent);
  296.                 DrawString('12');
  297.                 MoveTo(-cxSize + 1, 0 + fInfo.ascent div 2);
  298.                 DrawString('9');
  299.                 ForeColor(blackColor);
  300.             end
  301.         else
  302.             begin
  303.                 if settings.black then
  304.                     ForeColor(whiteColor);
  305.                 PenMode(patXor);
  306.                 MoveTo(0 - StringWidth('VI') div 2, cySize - 2);
  307.                 DrawString('VI');
  308.                 MoveTo(cxSize - 0 - StringWidth('III'), 0 + fInfo.ascent div 2);
  309.                 DrawString('III');
  310.                 MoveTo(0 - StringWidth('XII') div 2, -cySize + 0 + fInfo.ascent);
  311.                 DrawString('XII');
  312.                 MoveTo(-cxSize + 1, 0 + fInfo.ascent div 2);
  313.                 DrawString('IX');
  314.                 ForeColor(blackColor);
  315.             end;
  316.  
  317. {Draw the rest of the marks}
  318.         MoveTo(Trunc((cxSize - 2) * 0.866), Trunc((cySize - 2) * 0.5));
  319.         Line(0, 0);
  320.         MoveTo(Trunc((cxSize - 2) * 0.5), Trunc((cySize - 2) * 0.866));
  321.         Line(0, 0);
  322.         MoveTo(-Trunc((cxSize - 2) * 0.866), Trunc((cySize - 2) * 0.5));
  323.         Line(0, 0);
  324.         MoveTo(-Trunc((cxSize - 2) * 0.5), Trunc((cySize - 2) * 0.866));
  325.         Line(0, 0);
  326.         MoveTo(Trunc((cxSize - 2) * 0.866), -Trunc((cySize - 2) * 0.5));
  327.         Line(0, 0);
  328.         MoveTo(Trunc((cxSize - 2) * 0.5), -Trunc((cySize - 2) * 0.866));
  329.         Line(0, 0);
  330.         MoveTo(-Trunc((cxSize - 2) * 0.866), -Trunc((cySize - 2) * 0.5));
  331.         Line(0, 0);
  332.         MoveTo(-Trunc((cxSize - 2) * 0.5), -Trunc((cySize - 2) * 0.866));
  333.         Line(0, 0);
  334.  
  335. {Draw EK}
  336.         MoveTo(0, cySize div 2); {5}
  337.         EK;
  338.  
  339.         DrawHands(dateTime);
  340.  
  341.         gPrevDateTime := dateTime;
  342.     end; {ShowClock}
  343.  
  344.     procedure BackgroundTask;
  345.         var
  346.             dateTime: DateTimeRec;    {• date gets read into here */}
  347.     begin
  348.         GetTime(dateTime);
  349.         if (dateTime.minute <> gPrevDateTime.minute) or (settings.seconds and (dateTime.second <> gPrevDateTime.second)) then
  350.             begin
  351.                 SetPort(clockWindow);
  352.                 PenMode(srcXor);
  353.                 DrawHands(gPrevDateTime);
  354.                 PenMode(srcXor);
  355.                 DrawHands(dateTime);
  356.                 gPrevDateTime := dateTime;
  357.             end;
  358.     end; {BackgroundTask}
  359.  
  360.     procedure SetUpWindow;
  361.         var
  362.             wr: Rect;
  363.     begin
  364. {$IFC UNDEFINED THINK_PASCAL}
  365.         dragRect := qd.screenBits.bounds;
  366. {$ELSEC}
  367.         dragRect := screenBits.bounds;
  368. {$ENDC}
  369.  
  370. {Color doesn't matter yet, but why not prepare for it?}
  371.         if gColorQDFlag then
  372.             clockWindow := GetNewCWindow(128, nil, WindowPtr(-1))
  373.         else
  374.             clockWindow := GetNewWindow(128, nil, WindowPtr(-1));
  375.         SetPort(clockWindow);
  376.     end; {SetUpWindow}
  377.  
  378.     procedure SetUpMenus;
  379.     begin
  380.         appleMenu := NewMenu(appleID, stringof(char($14)));
  381.         InsertMenu(appleMenu, 0);
  382.         fileMenu := NewMenu(fileID, 'File');
  383.         InsertMenu(fileMenu, 0);
  384.         editMenu := NewMenu(editID, 'Edit');
  385.         InsertMenu(editMenu, 0);
  386.         optionsMenu := NewMenu(optionsID, 'Options');
  387.         InsertMenu(optionsMenu, 0);
  388.         AppendMenu(appleMenu, 'About NewWatch…');
  389. {$IFC UNDEFINED THINK_PASCAL}
  390.         AppendResMenu(appleMenu, 'DRVR');
  391. {$ELSEC}
  392.         AddResMenu(appleMenu, 'DRVR');
  393. {$ENDC}
  394.         AppendMenu(fileMenu, 'Help/H;Standard size/N;(-;Quit/Q');
  395.         AppendMenu(editMenu, 'Undo/Z;(-;Cut/X;Copy/C;Paste/V;Clear');
  396.         AppendMenu(optionsMenu, 'White;Black;(-;Dots;Arabic;Roman;(-;Show seconds;Thick hands');
  397.         DrawMenuBar;
  398.     end; {SetUpMenus}
  399.  
  400.     procedure AdjustMenus;
  401.         var
  402.             wp: WindowPeek;
  403.             kind: Integer;
  404.             DA: Boolean;
  405.         procedure Enable (menu: MenuHandle; item: Integer; ok: Boolean);
  406.         begin
  407.             if ok then
  408.                 EnableItem(menu, item)
  409.             else
  410.                 DisableItem(menu, item);
  411.         end; {Enable}
  412.     begin
  413.         wp := WindowPeek(FrontWindow);
  414.         if wp = nil then
  415.             kind := 0
  416.         else
  417.             kind := wp^.windowKind;
  418.         DA := kind < 0;
  419.  
  420.         Enable(editMenu, 1, DA);
  421.         Enable(editMenu, 3, DA);
  422.         Enable(editMenu, 4, DA);
  423.         Enable(editMenu, 5, DA);
  424.         Enable(editMenu, 6, DA);
  425.  
  426.         CheckItem(optionsMenu, 1, not settings.black);
  427.         CheckItem(optionsMenu, 2, settings.black);
  428.  
  429.         CheckItem(optionsMenu, 4, settings.display = 0);
  430.         CheckItem(optionsMenu, 5, settings.display = 1);
  431.         CheckItem(optionsMenu, 6, settings.display = 2);
  432.  
  433.         CheckItem(optionsMenu, 8, settings.seconds);
  434.         CheckItem(optionsMenu, 9, settings.fancy);
  435.     end; {AdjustMenus}
  436.  
  437.     procedure HandleMenu (mSelect: LongInt);
  438.         var
  439.             menuID: Integer;
  440.             menuItem: Integer;
  441.             name: Str255;
  442.             savePort: GrafPtr;
  443.             theFrontWindow: WindowPeek;
  444.     begin
  445.         menuID := HiWrd(mSelect);
  446.         menuItem := LoWrd(mSelect);
  447.  
  448.         case menuID of
  449.             appleID: 
  450.                 if menuItem = 1 then
  451.                     begin
  452.                         if Alert(128, nil) = 1 then {About…}
  453.                             ;
  454.                     end
  455.                 else
  456.                     begin
  457.                         GetPort(savePort);
  458. {$IFC UNDEFINED THINK_PASCAL}
  459.                         GetMenuItemText(appleMenu, menuItem, name);
  460. {$ELSEC}
  461.                         GetItem(appleMenu, menuItem, name);
  462. {$ENDC}
  463.                         if OpenDeskAcc(name) = 0 then
  464.                             ;
  465.                         SetPort(savePort);
  466.                     end;
  467.             fileID: 
  468.                 case menuItem of
  469.                     helpItem: 
  470.                         begin
  471.                             if Alert(129, nil) = 1 then {Show help text}
  472.                                 ;
  473.                         end;
  474.                     defaultItem: 
  475.                         begin
  476.                             SizeWindow(clockWindow, 32, 32, false);
  477.                             SetPort(clockWindow);
  478.                             InvalRect(clockWindow^.portRect);
  479. {Move it to some safe place too}
  480.                             MoveWindow(clockWindow, 40, 40, true);
  481.                         end;
  482.                     quitItem: 
  483.                         gDone := true;
  484.                 end; {case}
  485.             editID: 
  486.                 if not SystemEdit(menuItem - 1) then
  487.                     SysBeep(5);
  488.             optionsID: 
  489.                 begin
  490.                     case menuItem of
  491.                         1: 
  492.                             settings.black := false;
  493.                         2: 
  494.                             settings.black := true;
  495.                         8: 
  496.                             settings.seconds := not settings.seconds;
  497.                         9: 
  498.                             settings.fancy := not settings.fancy;
  499.                         otherwise
  500.                             settings.display := menuItem - 4;
  501.                     end; {case}
  502.                     InvalRect(clockWindow^.portRect);
  503.                     AdjustMenus;
  504.                 end;
  505.         end;
  506.     end; {HandleMenu}
  507.  
  508.     procedure InitMacintosh;
  509.         const
  510.             _WaitNextEvent = $A860;
  511.             _Unimplemented = $A89F;
  512.             _GetCIcon = $AA1E; {E.g. any Color QuickDraw routine}
  513.             k32bQD = $AB1D;
  514.     begin
  515. {$IFC UNDEFINED THINK_PASCAL}
  516.         MaxApplZone;
  517.  
  518.         InitGraf(@qd.thePort);
  519.         InitFonts;
  520.         FlushEvents(everyEvent, 0);
  521.         InitWindows;
  522.         InitMenus;
  523.         TEInit;
  524.         InitDialogs(nil);
  525. {$ENDC}
  526.         InitCursor;
  527.  
  528.         gHasWNE := NGetTrapAddress(_WaitNextEvent, ToolTrap) <> NGetTrapAddress(_Unimplemented, ToolTrap);
  529.         gColorQDFlag := NGetTrapAddress(_GetCIcon, ToolTrap) <> NGetTrapAddress(_Unimplemented, ToolTrap);
  530.         g32bQDFlag := NGetTrapAddress(k32bQD, ToolTrap) <> NGetTrapAddress(_Unimplemented, ToolTrap);
  531.     end;
  532.  
  533.     procedure HandleMouseDown (var theEvent: EventRecord);
  534.         var
  535.             theWindow: WindowPtr;
  536.             windowCode: Integer;
  537.             growResult: Longint;
  538.     begin
  539.         windowCode := FindWindow(theEvent.where, theWindow);
  540.  
  541.         case windowCode of
  542.             inSysWindow: 
  543.                 SystemClick(theEvent, theWindow);
  544.             inMenuBar: 
  545.                 begin
  546.                     AdjustMenus;
  547.                     HandleMenu(MenuSelect(theEvent.where));
  548.                 end;
  549.             inDrag:  {We should not have any, but just in case someone hacks it…}
  550.                 if theWindow = clockWindow then
  551.                     DragWindow(clockWindow, theEvent.where, dragRect);
  552.             inContent: 
  553.                 if theWindow = clockWindow then
  554.                     begin
  555.                         if theWindow <> FrontWindow then
  556.                             SelectWindow(clockWindow)
  557.                         else if BAnd(theEvent.modifiers, optionKey) <> 0 then {Option-klick = resize!}
  558.                             begin
  559.                                 growResult := GrowWindow(clockWindow, theEvent.where, GetGrayRgn^^.rgnBBox);
  560.                                 if growResult <> 0 then
  561.                                     begin
  562.                                         SizeWindow(clockWindow, LoWrd(growResult), HiWrd(growResult), false);
  563.                                         SetPort(clockWindow);
  564.                                         InvalRect(clockWindow^.portRect);
  565.                                     end;
  566.                             end
  567.                         else
  568.                             DragWindow(clockWindow, theEvent.where, dragRect);
  569.                     end;
  570. { inGoAway: }
  571. { if (theWindow = clockWindow) then if TrackGoAway(clockWindow, theEvent.where) then}
  572. { gDone := true;}
  573.         end;
  574.     end;
  575.  
  576.     procedure HandleEvent;
  577.         var
  578.             ok: Boolean;
  579.             theEvent: EventRecord;
  580.     begin
  581.         HiliteMenu(0);
  582.  
  583.         if gHasWNE then
  584.             ok := WaitNextEvent(everyEvent, theEvent, 60, nil) {sleeptime of 1 second - we can't need more if we have a seconds hand!}
  585.         else
  586.             begin
  587.                 SystemTask;        {• Handle desk accessories.}
  588.                 ok := GetNextEvent(everyEvent, theEvent);
  589.             end;
  590.  
  591.         if ok then
  592.             case theEvent.what of
  593.                 mouseDown: 
  594.                     HandleMouseDown(theEvent);
  595.                 keyDown, autoKey: 
  596.                     if BAnd(theEvent.modifiers, cmdKey) <> 0 then
  597.                         begin
  598.                             AdjustMenus;
  599.                             HandleMenu(MenuKey(char(BAnd(theEvent.message, charCodeMask))));
  600.                         end;
  601.                 updateEvt: 
  602.                     begin
  603. {Because of the xor-based updates, I can't just update a part of the window, but must}
  604. {invalidate all of it!}
  605.                         SetPort(clockWindow);
  606.                         InvalRect(clockWindow^.portRect);
  607. {After that, a normal update!}
  608.                         BeginUpdate(clockWindow);
  609.                         ShowClock;
  610.                         EndUpdate(clockWindow);
  611.                     end;
  612.                 activateEvt: 
  613.                     InvalRect(clockWindow^.portRect);
  614.             end
  615.         else
  616.             BackgroundTask;
  617.     end; {HandleEvent}
  618.  
  619. { main program }
  620. begin
  621.     InitMacintosh;
  622.     SetUpMenus;
  623.     SetUpWindow;
  624.     settings := SettingsType(GetWRefCon(clockWindow));
  625.     ShowClock;
  626.  
  627.     while not gDone do
  628.         HandleEvent;
  629.  
  630.     SetPort(clockWindow);
  631.  
  632.     wt := WindowTHnd(GetResource('WIND', 128));
  633.     wt^^.boundsRect := clockWindow^.portRect;
  634.     LocalToGlobal(wt^^.boundsRect.topLeft);
  635.     LocalToGlobal(wt^^.boundsRect.botRight);
  636.     wt^^.refCon := Longint(settings);
  637.     ChangedResource(Handle(wt));
  638.  
  639. end.